﻿using System.ComponentModel;
using System.Globalization;
using System.Runtime.CompilerServices;

namespace System;

//
// 摘要:
//     Extension methods for all objects.
public static class ObjectExtensions {
    //
    // 摘要:
    //     Used to simplify and beautify casting an object to a type.
    //
    // 参数:
    //   obj:
    //     Object to cast
    //
    // 类型参数:
    //   T:
    //     Type to be casted
    //
    // 返回结果:
    //     Casted object
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static T As<T>(this object obj) where T : class {
        return (T)obj;
    }

    //
    // 摘要:
    //     Converts given object to a value type using System.Convert.ChangeType(System.Object,System.Type)
    //     method.
    //
    // 参数:
    //   obj:
    //     Object to be converted
    //
    // 类型参数:
    //   T:
    //     Type of the target object
    //
    // 返回结果:
    //     Converted object
    public static T To<T>(this object obj) where T : struct {
        if (typeof(T) == typeof(Guid)) {
            return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(obj.ToString());
        }

        return (T)Convert.ChangeType(obj, typeof(T), CultureInfo.InvariantCulture);
    }

    //
    // 摘要:
    //     Check if an item is in a list.
    //
    // 参数:
    //   item:
    //     Item to check
    //
    //   list:
    //     List of items
    //
    // 类型参数:
    //   T:
    //     Type of the items
    public static bool IsIn<T>(this T item, params T[] list) {
        return list.Contains(item);
    }

    //
    // 摘要:
    //     Check if an item is in the given enumerable.
    //
    // 参数:
    //   item:
    //     Item to check
    //
    //   items:
    //     Items
    //
    // 类型参数:
    //   T:
    //     Type of the items
    public static bool IsIn<T>(this T item, IEnumerable<T> items) {
        return items.Contains(item);
    }

    //
    // 摘要:
    //     Can be used to conditionally perform a function on an object and return the modified
    //     or the original object. It is useful for chained calls.
    //
    // 参数:
    //   obj:
    //     An object
    //
    //   condition:
    //     A condition
    //
    //   func:
    //     A function that is executed only if the condition is
    //
    //     true
    //
    // 类型参数:
    //   T:
    //     Type of the object
    //
    // 返回结果:
    //     Returns the modified object (by the func if the condition is
    //
    //     true
    //
    //     ) or the original object if the condition is
    //
    //     false
    public static T If<T>(this T obj, bool condition, Func<T, T> func) {
        if (condition) {
            return func(obj);
        }

        return obj;
    }

    //
    // 摘要:
    //     Can be used to conditionally perform an action on an object and return the original
    //     object. It is useful for chained calls on the object.
    //
    // 参数:
    //   obj:
    //     An object
    //
    //   condition:
    //     A condition
    //
    //   action:
    //     An action that is executed only if the condition is
    //
    //     true
    //
    // 类型参数:
    //   T:
    //     Type of the object
    //
    // 返回结果:
    //     Returns the original object.
    public static T If<T>(this T obj, bool condition, Action<T> action) {
        if (condition) {
            action(obj);
        }

        return obj;
    }
}
